package initdatabase

import (
	"context"
	"fmt"
	"github.com/lexkong/log"
	"github.com/spf13/viper"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"strconv"
	"time"
)

func initMgo() *mongo.Client {
	url := viper.GetString("mongo.addrs")
	poolSize := uint64(viper.GetInt("mongo.poollimit"))
	timeout := viper.GetInt64("mongo.timeout")
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(url).SetMaxPoolSize(poolSize))
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("Successful database link")
	return client

}

type Mgo struct {
	database   string
	collection string
}

func NewMongo(Database, Collection string) *Mgo {
	return &Mgo{
		database:   Database,
		collection: Collection,
	}
}

//插入单个
func (m *Mgo) InsertOne(value interface{}) *mongo.InsertOneResult {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	insertResult, err := collection.InsertOne(context.TODO(), value)
	if err != nil {
		fmt.Println(err)
	}
	return insertResult
}

//按条件查询多个 sort 1 ，-1 . 1 为最初时间读取 -1 为最新时间读取   Skip 跳过 Limit 读取数量
func (m *Mgo) CollectionDocuments(sort int, limit int64, skip int64, filter interface{}) *mongo.Cursor {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	SORT := bson.D{{"_id", sort}}
	findOptions := options.Find().SetSort(SORT).SetLimit(limit).SetSkip(skip)
	cur, err := collection.Find(context.TODO(), filter, findOptions)
	if err != nil {
		log.Errorf(err, "cur error")
		panic(err)
	}
	return cur
}

// 查询单个
func (m *Mgo) FindOne(key string, value interface{}) *mongo.SingleResult {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	//collection.
	filter := bson.D{{key, value}}
	singleResult := collection.FindOne(context.TODO(), filter)
	return singleResult
}

func (m *Mgo) FInd(filter interface{}) *mongo.Cursor {

	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	cur, err := collection.Find(context.TODO(), filter)
	if err != nil {
		log.Errorf(err, "cur error")
		panic(err)
	}
	return cur

}

//bson 单查询
func (m *Mgo) BsonFindOne(filter bson.D) *mongo.SingleResult {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	fmt.Println(filter)
	fi := bson.D{{"User", bson.D{{"Number", "541612010327"}}}}
	singleResult := collection.FindOne(context.TODO(), fi)
	return singleResult
}

//查询集合里有多少数据
func (m *Mgo) CollectionCount() (string, int64) {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	name := collection.Name()
	size, _ := collection.EstimatedDocumentCount(context.TODO())
	return name, size
}

//获取集合创建时间和编号
func (m *Mgo) ParsingId(result string) (time.Time, uint64) {
	temp1 := result[:8]
	timestamp, _ := strconv.ParseInt(temp1, 16, 64)
	dateTime := time.Unix(timestamp, 0) //这是截获情报时间 时间格式 2019-04-24 09:23:39 +0800 CST
	temp2 := result[18:]
	count, _ := strconv.ParseUint(temp2, 16, 64) //截获情报的编号
	return dateTime, count
}

//删除文章
func (m *Mgo) Delete(key string, value interface{}) int64 {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	filter := bson.D{{key, value}}
	count, err := collection.DeleteOne(context.TODO(), filter, nil)
	if err != nil {
		fmt.Println(err)
	}
	return count.DeletedCount

}

//删除多个
func (m *Mgo) DeleteMany(key string, value interface{}) int64 {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	filter := bson.D{{key, value}}

	count, err := collection.DeleteMany(context.TODO(), filter)
	if err != nil {
		fmt.Println(err)
	}
	return count.DeletedCount
}

// 更新

func (m *Mgo) Update(key, value string, b bool) {
	client := DB.Mongo
	collection := client.Database(m.database).Collection(m.collection)
	filter := bson.D{{key, value}}
	update := bson.D{{"$set", bson.D{{"admin", b}}}}
	if _, err := collection.UpdateOne(context.TODO(), filter, update); err != nil {
		fmt.Println(err)
	}
}
